package org.devf.fork.imsimulator.socket;

import cn.hutool.json.JSONUtil;
import org.devf.fork.imsimulator.help.MyLog;
import org.devf.fork.imsimulator.help.ThreadUtil;
import org.devf.fork.imsimulator.socket.dto.BasePackets;
import org.devf.fork.imsimulator.socket.handler.MsgHandlerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * ReceiveRunable related
 *
 * @author wanghuafu
 * @since 1.0  2023/9/12 15:25
 */
public class ReceiveRunnable implements Runnable {
    private final InputStream serverInput;
    private final Channel channel;
    private TcpPacket lastPacket;
    private final ExecutorService executorService = Executors.newFixedThreadPool(1);

    public ReceiveRunnable(InputStream serverInput, Channel channel) {
        this.serverInput = serverInput;
        this.channel = channel;

    }


    @Override
    public void run() {
        byte[] vData = new byte[1024];//容器
        byte[] destData;
        while (!SocketConfig.isStopRead) {
            try {
                int count = serverInput.read(vData);
                if (-1 == count) {
                    ThreadUtil.safeSleep(100);
                    continue;
                }

                destData = new byte[count];
                System.arraycopy(vData, 0, destData, 0, count);

                //读取数据，组装消息
                for (int tOffset = 0; tOffset < destData.length; ) {
                    if (null == lastPacket) {
                        lastPacket = new TcpPacket();
                    }

                    tOffset = lastPacket.append(destData, tOffset);

                    if (lastPacket.isComplete()) {
                        doDelivery(lastPacket);
                        lastPacket = null;
                    }
                }

            } catch (SocketException e) {
                MyLog.info("error:"+e.getMessage());
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                destData = null;
            }
        }

    }

    protected void doDelivery(TcpPacket lastPacket) {
        executorService.submit(() -> {
            BasePackets basePackets = JSONUtil.toBean(new String(lastPacket.getData()), BasePackets.class);
            System.out.println("收到指令消息："+JSONUtil.toJsonStr(basePackets));
            for (Ihandler handler : MsgHandlerFactory.findHandlers()) {
                try {
                    if (handler.isSupport(basePackets)) {
                        handler.execute(this.channel, basePackets);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }


}
